package com.hundsun.data.main;

import com.hundsun.data.mapper.dmoracle.DmTableMapper;
import com.hundsun.data.mapper.oracle.OracleTableMapper;
import com.hundsun.data.mapper.tdsqlmysql.TdTableMapper;
import com.hundsun.data.po.TableInfoPo;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 数据库差异对比
 */
@Slf4j
public class DatabaseComparisonTest {

    public static void main(String[] args) throws IOException {
        Map<String, List<TableInfoPo>> oracleTableInfos = executeOracle();
//        Map<String, List<TableInfoPo>> tdTableInfos = executeTDMySQL();
//        compareTableInfos(oracleTableInfos, tdTableInfos);
//        executeDMOracle();
        oracleTableInfos.forEach((k, v) -> {
            log.info("{} = {}", k, v);
        });
    }

    private static void compareTableInfos(Map<String, List<TableInfoPo>> oracleTableInfos, Map<String, List<TableInfoPo>> tdTableInfos) {
        List<String> diffOracleKeys = oracleTableInfos.keySet().stream().filter(f -> !tdTableInfos.containsKey(f)).toList();
        List<String> diffTdKeys = tdTableInfos.keySet().stream().filter(f -> !oracleTableInfos.containsKey(f)).toList();
        log.info("diffOracleKeys = {}, diffTdKeys = {}", diffOracleKeys, diffTdKeys);
    }

    private static Map<String, List<TableInfoPo>> executeOracle() throws IOException {
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config-oracle.xml"));
        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            OracleTableMapper oracleTableMapper = sqlSession.getMapper(OracleTableMapper.class);
//            List<String> tables = oracleTableMapper.selectAllTables();
            List<TableInfoPo> tableInfos = oracleTableMapper.selectTableInfo(null);
            return tableInfos.stream().collect(Collectors.groupingBy(TableInfoPo::getTableName));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static Map<String, List<TableInfoPo>> executeTDMySQL() throws IOException {
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config-tdsqlmysql.xml"));
        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            TdTableMapper tdTableMapper = sqlSession.getMapper(TdTableMapper.class);
//            List<String> tables = tdTableMapper.selectAllTables();
            List<TableInfoPo> tableInfos = tdTableMapper.selectTableInfo(null);
            return tableInfos.stream().collect(Collectors.groupingBy(TableInfoPo::getTableName));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static Map<String, List<TableInfoPo>> executeDMOracle() throws IOException {
        Map<String, List<TableInfoPo>> tableInfoCache = new HashMap<>();

        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config-dmoracle.xml"));
        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            DmTableMapper dmTableMapper = sqlSession.getMapper(DmTableMapper.class);
            List<String> tables = dmTableMapper.selectAllTables();
            tables.forEach(f -> {
                List<TableInfoPo> tableInfos = dmTableMapper.selectTableInfo(f);
                tableInfoCache.put(f, tableInfos);
            });
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return tableInfoCache;
    }

}
